using System;
using System.ComponentModel;
using System.IO;

namespace ImageUploaderComponent.Data{
    public abstract class MediaviewModelBase : INotifyPropertyChanged{
        protected MediaData imageData;
        protected bool isUploading;
        protected bool isDeletable;
        private string statusTooltipMessage;
        private FileInfo imageFileInfo;
        private UploadStatus status;
        protected double progress;
        private Uri statusImageUri;

        /// <summary>
        /// Do not use! The dataitem must not be externally modifiable after creation.  
        /// This is only exposed for deserialization, and will eventually be replaced with a memento pattern.
        /// </summary>
        public MediaData DataItem{
            get { return imageData; }
            protected set { imageData = value; }

        }

        public Guid Key {
            get {
                return imageData.Key;
            }
            set {
                imageData.Key = value;
                propertyChanged("Key");
            }
        }


        public string Description {
            get { return imageData.CommentText; }
            set {
                imageData.CommentText = value;
                propertyChanged("Description");
            }
        }

        public string Name {
            get { return imageData.ImageTitle; }
            set {
                if (value != imageData.ImageTitle) {
                    propertyChanged("Name");
                }
                imageData.ImageTitle = value;
            }
        }

        public string FileName {
            get { return imageData.FileName; }
            set {
                if (value != imageData.FileName) {
                    propertyChanged("FileName");
                }
                imageData.FileName = value;
            }
        }

        public byte[] ImageBytes {
            get { return imageData.ImageBytes; }
            set {
                if (value != imageData.ImageBytes) {
                    propertyChanged("ImageBytes");
                }
                imageData.ImageBytes = value;
            }
        }

        public int DisplayOrder {
            get { return imageData.DisplayOrder; }
            set {
                if (value != imageData.DisplayOrder) {
                    propertyChanged("DisplayOrder");
                }
                imageData.DisplayOrder = value;
            }
        }

        public bool IsUploading {
            get { return isUploading; }
            set {
                if (value != isUploading) {
                    propertyChanged("IsUploading");
                }
                isUploading = value;
            }
        }

        public bool IsDeletable {
            get { return isDeletable; }
            set {
                if (value != isDeletable) {
                    propertyChanged("IsDeletable");
                }
                isDeletable = value;
            }
        }

        public bool IsEnabled {
            get { return imageData.IsEnabled; }
            set {
                propertyChanged("IsEnabled");
                imageData.IsEnabled = value;
            }
        }

        public string StatusTooltipMessage {
            get { return statusTooltipMessage; }
            set {
                if (value != statusTooltipMessage) {
                    propertyChanged("StatusTooltipMessage");
                }
                statusTooltipMessage = value;
            }
        }

        public FileInfo ImageFileInfo {
            get { return imageFileInfo; }
            set {
                if (value != imageFileInfo) {
                    propertyChanged("ImageFileInfo");
                }
                imageFileInfo = value;
            }
        }

        public UploadStatus Status {
            get { return status; }
            set {
                status = value;
                propertyChanged("Status");
                setStatusSetImageFileName(value);
            }
        }

        public double Progress {
            get { return progress; }
            set {
                if (value != progress) {
                    propertyChanged("Progress");
                }
                progress = value;
            }
        }

        public Uri StatusImageUri {
            get { return statusImageUri; }
            set {
                statusImageUri = value;
                propertyChanged("StatusImageUri");
            }
        }

        public Uri ImageUri{
            get {
                return imageData.ImageUri;
            }
            set {
                imageData.ImageUri = value;
            }
        }

        private void setStatusSetImageFileName(UploadStatus value) {
            if (value == UploadStatus.Success) {
                StatusImageUri = new Uri("complete.png", UriKind.Relative);
                StatusTooltipMessage = "Uploaded successfully.";
                return;
            }
            if (value == UploadStatus.Started) {
                StatusImageUri = new Uri("pending.png", UriKind.Relative);
                StatusTooltipMessage = "Uploading";
                return;
            }
            if (value == UploadStatus.InvalidExtension) {
                StatusImageUri = new Uri("error.png", UriKind.Relative);
                isDeletable = true;
                StatusTooltipMessage = "Only .png and .jpg files are currently supported.  Not uploaded";
                progress = 0;
            }
        }

        public virtual event PropertyChangedEventHandler PropertyChanged;

        protected void propertyChanged(string propertyName) {
            if (PropertyChanged != null) {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        public abstract UploadStatus validateMedia();
        protected abstract bool isLegalFileExtension(string fileName);
    }
}